package rsj.manager;

import com.alibaba.fastjson.JSON;
import com.rlyy.aibase.utils.base.Node;
import common.util.DateTimeFormatterUtil;
import common.util.TransactionUtil;
import common.util.UUIDUtil;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.stereotype.Component;
import rsj.context.ApplicationContextUtil;
import rsj.dao.BaseDao;
import rsj.dao.OperateAuDao;
import rsj.dao.OrgPStatusDao;
import rsj.dao.OrgpDao;
import rsj.utils.RedisUtils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;

import static rsj.util.RedisKeyFactory.wrapSecret;

@Component
public class OrgProManager {

    private static final OrgProManager instance = new OrgProManager();

    public static OrgProManager getInstance() {
        return instance;
    }

    /*
        aut_id               调用者唯一标识，16位
        aut_signkey                签名需要的秘钥，32位
        aut_secretkey                加密需要的秘钥，32位
        aut_keyversion                秘钥版本
        aut_ctime                 秘钥生成时间
        aut_endtime                 秘钥过期时间
    */


    /*  sta_org_id		机构ID
        sta_prod_id		产品ID
        sta_status		机构产品状态
        sta_orgp_id		合同ID
    */
    private static final OrgpDao orgpDao = OrgpDao.getInstance();
    private static final OrgPStatusDao orgPStatusDao = OrgPStatusDao.getInstance();
    private static final OperateAuDao operateAuDao = OperateAuDao.getInstance();

    public String applyProd(String prodId, String prodUid, String orgId, String applyStatus
            , String prodName, String tid) {

        return (String) BaseDao.invokeSql(conn -> {
            return TransactionUtil.transactionInvoke(new TransactionUtil.TransactionInvoke() {
                @Override
                public Object invoke(Connection conn) {

                    // 1.添加机构产品表（合同表） 申请状态
                    String orgPId = orgpDao.insertApplyStatus(prodId, prodUid, orgId, applyStatus, prodName, conn);

                    // 2.新增或修改机构产品状态表 当前产品状态为 申请状态
                    orgPStatusDao.insertOrUpdateStatus(prodId, orgId, applyStatus, conn, orgPId);

//                    if (createAuth(conn, orgId, tid)) return orgPId;
                    return orgPId;
                }
            }, conn);
        });
    }


    /**
     * 生成python校验接口
     *
     * @param conn
     * @param orgId
     * @param tid
     */
    public boolean createAuth(Connection conn, String orgId, String tid) {
        // 3.添加调用python生成秘钥
        Node operateAu = operateAuDao.getByOrgId(orgId, conn);
        if (operateAu.valueInt() != 0) {
            return true;
        }

        // 4.3没有该用户的加密数据，则新增 更新数据
        insertOpeAndRedis(conn, orgId, tid);
        return false;
    }


    /**
     * 创建身份验证自动关闭连接
     *
     * @param orgId org id
     * @return boolean
     */
    public boolean createAuthAutoCloseConnection(String orgId) {
        DataSource dataSource = ApplicationContextUtil.getBean(DataSource.class);
        Connection connection = DataSourceUtils.getConnection(dataSource);
        try {
            return this.createAuth(connection, orgId, null);
        } finally {
            DataSourceUtils.releaseConnection(connection, dataSource);
        }
    }

    private void insertOpeAndRedis(Connection conn, String orgId, String tid) {
        String keyId = UUIDUtil.getUUID(16);
        String signKey = UUIDUtil.getUUID(32);
        String secretKey = UUIDUtil.getUUID(32);
        String keyVersion = "V1.0";
        Timestamp createTime = new Timestamp(new Date().getTime());
        Timestamp outTime = new Timestamp(DateUtils.addYears(new Date(), 100).getTime());

        HashMap<String, String> res = new HashMap();
        res.put("secret_key", secretKey);
        res.put("sign_key", signKey);
        res.put("key_id", keyId);
//        res.put("expire_time", new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(DateUtils.addYears(new Date(), 100)));
        res.put("expire_time", DateTimeFormatterUtil.dateTimeToString(DateTimeFormatterUtil.asLocalDateTime(DateUtils.addYears(new Date(), 100))));
        res.put("org_id", orgId);

        boolean response = RedisUtils.hset(wrapSecret(keyId), keyVersion, JSON.toJSONString(res));
//        int response = JedisUtil.hSet(wrapSecret(keyId), keyVersion, JSON.toJSONString(res), -1L, tid);
        if (!response) {
            throw new RuntimeException("redis存储秘钥失败！");
        }

        operateAuDao.insert(keyId, signKey, secretKey, keyVersion, createTime, outTime, conn, orgId);
    }
}
